﻿--MacaroonBound, a World of Warcraft® user interface addon.
--Copyright© 2008 Connor H. Chenoweth, aka Maul

MacaroonBoundSavedState = {}

local currentVersion = 30000.11
local spellBind, macroBind, ss = false, false

local match = string.match

local copyTable = Macaroon.copyTable
local clearTable = Macaroon.clearTable

function Macaroon.SpellBinder_OnLoad(self)

	local posCount, negCount, bindFrame = 5, 0

	self:RegisterEvent("SPELLS_CHANGED")
	self:RegisterEvent("UPDATE_BINDINGS"				)
	self:RegisterEvent("CURRENT_SPELL_CAST_CHANGED")
	self:RegisterEvent("SPELL_UPDATE_COOLDOWN")
	self:RegisterEvent("CRAFT_SHOW")
	self:RegisterEvent("CRAFT_CLOSE")
	self:RegisterEvent("TRADE_SKILL_SHOW")
	self:RegisterEvent("TRADE_SKILL_CLOSE")
	self:RegisterEvent("PET_BAR_UPDATE")

	ShowAllSpellRanksCheckBox:SetPoint("TOPLEFT", 74, -33)

	for i=1,12 do

		bindFrame = CreateFrame("Button", "MacaroonSpellBinder"..i, _G["SpellButton"..i], "MacaroonBindFrameTemplate")
		bindFrame.bindType = "spell"

		if (mod(i,2) == 0) then
			bindFrame:SetID(i+posCount)
			posCount = posCount - 1
		else
			bindFrame:SetID(i+negCount)
			 negCount = negCount - 1
		end

		bindFrame:SetPoint("TOPLEFT", _G["SpellButton"..i], "TOPLEFT", 0 ,0)
		bindFrame:SetPoint("BOTTOMRIGHT", _G["SpellButton"..i], "BOTTOMRIGHT", 0 ,0)
		bindFrame:SetFrameLevel(_G["SpellButton"..i]:GetFrameLevel()+1)

		_G["SpellButton"..i]:CreateFontString("$parentHotKey", "ARTWORK", "NumberFontNormalSmall")
		_G["SpellButton"..i.."HotKey"]:SetPoint("TOPRIGHT", -1, -5)
	end
end

function Macaroon.SpellBinder_OnEvent(self, event, ...)

	local hotkey, bindFrame, bound, spell, spellid, subSpellName

	if ( event == "SPELLS_CHANGED" or "UPDATE_BINDINGS") then

		if ( SpellBookFrame:IsVisible() ) then

			for i=1,12 do

				hotkey = _G["SpellButton"..i.."HotKey"]
				hotkey:SetText()

				bindFrame = _G["MacaroonSpellBinder"..i]
				bindFrame.spell = nil
				bindFrame.bindTable = ss.spells

				spellid = SpellBook_GetSpellID(bindFrame:GetID())

				if (spellid) then
					spell, subSpellName = GetSpellName(spellid, SpellBookFrame.bookType)
				end

				if (spell) then

					if (subSpellName) then
						spell = spell.."("..subSpellName..")"
					else
						spell = spell.."()"
					end

					bindFrame.spell = spell

					if (ss.spells) then
						bound = ss.spells[spell]
					end

					if (bound) then
						hotkey:SetText(match(bound.hotKeyText, "^:([^:]+)") or "")
					end
				end
			end
		end
	end
end

function Macaroon.SpellBinder_OnClick(self, button, silent)

	if (spellBind) then

		spellBind = false
		self:SetButtonState("NORMAL")

		if (not silent) then PlaySound("igMainMenuOptionCheckBoxOff") end

		for i=1,12 do
			_G["MacaroonSpellBinder"..i]:Hide()
		end
	else
		spellBind = true
		self:SetButtonState("PUSHED", 1)

		if (not silent) then PlaySound("igMainMenuOptionCheckBoxOn") end

		for i=1,12 do
			_G["MacaroonSpellBinder"..i]:Show()
		end
	end

end

function Macaroon.SpellBinder_OnShow(self)

end

function Macaroon.SpellBinder_OnHide(self)
	spellBind = true
	Macaroon.SpellBinder_OnClick(self, nil, true)
end

local function macroBinder_Update()

	if (MacroFrame) then

		local name, body, hotkey, bindFrame, bound

		for i=1,36 do

			hotkey = _G["MacroButton"..i.."HotKey"]
			bindFrame = _G["MacaroonMacroBinder"..i]
			bindFrame.macro = nil
			bindFrame.bindTable = ss.macros

			if (hotkey) then

				hotkey:SetText()

				macro, _, body, _ = GetMacroInfo(MacroFrame.macroBase + i)

				bindFrame.macro = macro

				if (ss.macros) then
					bound = ss.macros[macro]
				end

				if (bound) then
					hotkey:SetText(match(bound.hotKeyText, "^:([^:]+)") or "")
				end
			end
		end
	end
end

local function macroBinderAddonLoaded(addon)

	if (addon == "Blizzard_MacroUI") then

		hooksecurefunc("MacroFrame_Show", macroBinder_Update)
		hooksecurefunc("MacroFrame_Update", macroBinder_Update)

		local bindFrame

		MacaroonMacroBinderKeyBind:SetParent("MacroFrame")
		MacaroonMacroBinderKeyBind:SetPoint("TOPLEFT", "MacroFrame", "TOPLEFT", 80, -13)
		MacaroonMacroBinderKeyBind:Show()

		for i=1,36 do

			bindFrame = _G["MacaroonMacroBinder"..i]
			bindFrame:SetID(i)
			bindFrame:SetParent("MacroButton"..i)
			bindFrame:SetPoint("TOPLEFT", _G["MacroButton"..i], "TOPLEFT", 0 ,0)
			bindFrame:SetPoint("BOTTOMRIGHT", _G["MacroButton"..i], "BOTTOMRIGHT", 0 ,0)
			bindFrame:SetFrameLevel(_G["MacroButton"..i]:GetFrameLevel()+1)

			_G["MacroButton"..i]:CreateFontString("$parentHotKey", "ARTWORK", "NumberFontNormalSmall")
			_G["MacroButton"..i.."HotKey"]:SetPoint("TOPRIGHT", -1, -5)
		end
	end

end

function Macaroon.MacroBinder_OnLoad(self)

	local bindFrame

	self:RegisterEvent("ADDON_LOADED")
	self:RegisterEvent("UPDATE_BINDINGS")

	CREATE_MACROS = " "

	for i=1,36 do
		bindFrame = CreateFrame("Button", "MacaroonMacroBinder"..i, self, "MacaroonBindFrameTemplate")
		bindFrame.bindType = "macro"
		bindFrame:Hide()
	end
end

function Macaroon.MacroBinder_OnEvent(self, event, ...)

	if (event == "ADDON_LOADED") then
		macroBinderAddonLoaded(...)
	end

	macroBinder_Update()
end

function Macaroon.MacroBinder_OnClick(self, button, silent)

	if (macroBind) then

		macroBind = false
		self:SetButtonState("NORMAL")

		if (not silent) then PlaySound("igMainMenuOptionCheckBoxOff") end

		for i=1,36 do
			_G["MacaroonMacroBinder"..i]:Hide()
		end
	else
		macroBind = true
		self:SetButtonState("PUSHED", 1)

		if (not silent) then PlaySound("igMainMenuOptionCheckBoxOn") end

		for i=1,36 do
			_G["MacaroonMacroBinder"..i]:Show()
		end
	end
end

function Macaroon.MacroBinder_OnShow(self)

end

function Macaroon.MacroBinder_OnHide(self)
	macroBind = true
	Macaroon.MacroBinder_OnClick(self, nil, true)
end

function Macaroon.BoundLoadSavedData(saved)

	if (saved) then

		local savedState = copyTable(saved)

		if (savedState.spells) then

			for spell,_ in pairs(savedState.spells) do
				--temp fix
				if (ss.spells[spell] and ss.spells[spell].hotKeys) then
					ss.spells[spell].hotKeys = gsub(ss.spells[spell].hotKeys, "»", ":")
					ss.spells[spell].hotKeyText = gsub(ss.spells[spell].hotKeyText, "»", ":")
				end
				Macaroon.ApplySpellBindings(spell)
			end
		end

		if (savedState.macros) then

			for macro,_ in pairs(savedState.macros) do
				--temp fix
				if (ss.macros[macro] and ss.macros[macro].hotKeys) then
					ss.macros[macro].hotKeys = gsub(ss.macros[macro].hotKeys, "»", ":")
					ss.macros[macro].hotKeyText = gsub(ss.macros[macro].hotKeyText, "»", ":")
				end
				Macaroon.ApplyMacroBindings(macro)
			end
		end
	end
end

function Macaroon.BoundSaveCurrentState()

	return ss, nil, "spells;macros"

end

function Macaroon.BoundUpdateElements()

	--empty func
end

function Macaroon.BoundSetSaved()

	if (MacaroonSavedState.useShared and MacaroonSharedSavedState[MacaroonSavedState.sharedProfile]) then
		ss = MacaroonSharedSavedState[MacaroonSavedState.sharedProfile]

		if (not ss) then
			ss = MacaroonBoundSavedState
		end
	else
		ss = MacaroonBoundSavedState
	end

	return ss
end

local function controlOnEvent(self, event, ...)

	if (event == "VARIABLES_LOADED") then

		Macaroon.BoundSetSaved()

		if (not ss.spells) then
			ss.spells = {}
		end

		if (not ss.macros) then
			ss.macros = {}
		end

		Macaroon.StatesToSave.bound = Macaroon.BoundSaveCurrentState
		Macaroon.SavedDataLoad.bound = Macaroon.BoundLoadSavedData
		Macaroon.SavedDataUpdate.bound = Macaroon.BoundUpdateElements
		Macaroon.SetSavedVars.bound = Macaroon.BoundSetSaved

	elseif (event == "PLAYER_LOGIN") then

		Macaroon.BoundLoadSavedData(ss)

	elseif (event == "PLAYER_ENTERING_WORLD") then
		playerEnteredWorld = true
	end
end


local frame = CreateFrame("Frame", nil, UIParent)
frame:SetScript("OnEvent", controlOnEvent)
frame:RegisterEvent("VARIABLES_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")